//Andrew Villadsen

import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.event.MouseInputAdapter;
import javax.vecmath.Vector3d;


//Class UserMouseInputListener monitors user mouse input for throwing controls.
public class UserMouseInputListener extends MouseInputAdapter
{
	private static final int MAX_ENTRIES = 100;
	private static final double K_CONST = 1.0;
	
	private ArrayList<Integer> x, y;
	
	private Disc disc;
	private Field field;
	
	
	public UserMouseInputListener(Disc d)
	{
		disc = d;
		x = new ArrayList<Integer>();
		y = new ArrayList<Integer>();
	}
	
	//Registers a new Disc to the listener. Returns the previously registered Disc, or null if no Disc was registered.
	public Disc registerDisc(Disc d)
	{
		Disc temp = disc;
		disc = d; 
		return temp;
	}
	
	//Sets the field.
	public void setField(Field f)
	{
		field = f;
	}
	
	//Adds the current point to the list if the maximum number of entries has not yet been reached.
	public void mouseDragged(MouseEvent e)
	{
		if(x.size() < MAX_ENTRIES)
		{
			x.add(e.getX());
			y.add(e.getY());
		}
	}
	
	//Performs curvature calculations and throws disc, if user is holding disc and has dragged far enough.
	public void mouseReleased(MouseEvent e)
	{
		if(field.playerWithDisc != null && field.playerWithDisc.routine instanceof UserMovementRoutine && x.size() > 2)
		{
			double velocity = 14.0;
			
			double curvature = 0.0;
			for(int i = 0; i < x.size() - 2; i++)
				curvature += (Math.atan2(y.get(i + 2) - y.get(i + 1), x.get(i + 2) - x.get(i + 1)) - Math.atan2(y.get(i + 2) - y.get(i + 1), x.get(i + 2) - x.get(i + 1))) / Math.hypot(x.get(i + 1) - x.get(i), y.get(i + 1) - y.get(i));
			curvature /= x.size() - 2;
			curvature *= K_CONST;
			

			double theta = Math.atan2(y.get(1) - y.get(0), x.get(1) - x.get(0));
			double phi = Math.PI / 15.0;

			disc.velocity = new Vector3d(velocity * Math.cos(phi) * Math.cos(theta), velocity * Math.cos(phi) * Math.sin(theta), velocity * Math.sin(phi));
			field.getHomeTeam().discChange(field.playerWithDisc);
			field.getAwayTeam().discChange(field.playerWithDisc);			
			((UserMovementRoutine) field.playerWithDisc.routine).heldDisc = null;
			field.playerWithDisc = null;
			((DiscMechanics) disc.routine).startThrow(curvature, Math.PI / 30.0);
		}
		x.clear();
		y.clear();
	}	
}